import Toybox.Graphics;
import Toybox.WatchUi;
import Toybox.Lang;
import Toybox.System;
import Toybox.Application;
import Toybox.Timer; // Import the Timer module

class NovelView extends WatchUi.View {

    hidden var _startLine as Number; // Track the starting line index for the current view
    hidden var _allLines as Array<String>; // Store all lines of the novel
    hidden var _font as Graphics.FontDefinition;
    hidden var _novelText as String; // Variable to hold the full novel text
    hidden var _linesPerPage as Number = 0;
    hidden var _isAutoScrolling as Boolean = false; // Track auto-scroll state
    hidden var _autoScrollTimer as Timer.Timer?; // Timer for auto-scrolling

    function initialize() {
        View.initialize();
        _startLine = 0;
        _allLines = [] as Array<String>;
        // Load font size from properties, default to FONT_SMALL
        var storedFontSize = Application.Storage.getValue("fontSize");
        if (storedFontSize != null) {
            _font = storedFontSize as Graphics.FontDefinition;
        } else {
            _font = Graphics.FONT_SMALL;
            Application.Storage.setValue("fontSize", _font);
        }
        // Placeholder novel text - replace with actual loading logic later
        _novelText = "《红色的起点》出版后，收到众多的读者来信。读者们热忱地鼓励我继续写下去。《红色的起点》写的是“中国有了共产党”​。那么，接下去该写什么呢？不言而喻，应该是“共产党有了领袖毛泽东”​。巧真巧，就在这时，上海电影制片厂筹拍关于遵
义会议的上下集大型故事片。上海电影制片厂文学部编辑程泽民前来我家，约我写这一电影剧本。我以为，遵义会议的重要意义，用一句话来概括，就是“历史选择了毛泽东（为什么是他？他有什么人格魅力？他是怎么做到的？​）​”​。也就是说，​“共产党有了领袖毛泽东”​。这一约稿，和我的写作计划不谋而合，于是，我也就答应下来。我在完成关于遵义会议的十几万字的电影文学剧本《历史选择了毛泽东（为什么是他？他有什么人格魅力？他是怎么做到的？​）​》之后，完成了同名纪实长篇《历史选择了毛泽东（为什么是他？他有什么人格魅力？他是怎么做到的？​）​》​。毛泽东是中国20世纪的伟人、巨人。有关他的传记，从《青年毛泽东》到《晚《红色的起点》出版后，收到众多的读者来信。读者们热忱地鼓励我继续写下去。《红色的起点》写的是“中国有了共产党”​。那么，接下去该写什么呢？不言而喻，应该是“共产党有了领袖毛泽东”​。巧真巧，就在这时，上海电影制片厂筹拍关于遵义会议的上下集大型故事片。上海电影制片厂文学部编辑程泽民前来我家，约我写这一电影剧本。我以为，遵义会议的重要意义，用一句话来概括，就是“历史选择了毛泽东（为什么是他？他有什
么人格魅力？他是怎么做到的？​）​”​。也就是说，​“共产党有了领袖毛泽东”​。这一约稿，和我的写作计划不谋而合，于是，我也就答应下
来。我在完成关于遵义会议的十几万字的电影文学剧本《历史选择了毛泽东（为什么是他？他有什么人格魅力？他是怎么做到的？​）​》之后，完成了同名纪实长篇《历史选择了毛泽东（为什么是他？他有什么人格魅力？他是怎么做到的？​）​》​。毛泽东是中国20世纪的伟人、巨人。有关他的传记，从《青年毛泽东》到《晚《红色的起点》出版后，收到众多的读者来信。读者们热忱地鼓励我继续写下去。《红色的起点》写的是“中国有了共产党”​。那么，接下去该写什么呢？不言而喻，应该是“共产党有了领袖毛泽东”​。巧真巧，就在这时影制片厂筹拍关于遵义会议的上下集大型故事片。上海电影制片厂文学部编辑程泽民前来我家，约我写这一电影剧本。我以为，遵义会议的重要意义，用一句话来概括，就是“历史选择了毛泽东（为什么是他？他有什么人格魅力？他是怎么做到的？​）​”​。也就是说，​“共产党
有了领袖毛泽东”​。这一约稿，和我的写作计划不谋而合，于是，我也就答应下来。我在完成关于遵义会议的十几万字的电影文学剧本《
历史选择了毛泽东（为什么是他？他有什么人格魅力？他是怎么做到的？​）​》之后，完成了同名纪实长篇《历史选择了毛泽东（为什么是他？他有什么人格魅力？他是怎么做到的？​）​》​。毛泽东是中国20世纪的伟人、巨人。有关他的传记，从《青年毛泽东》到《晚期毛泽东》​，已经有了好多本。本书从领袖史的特殊视角写毛泽东，从历史对中共领袖人物的选择写毛泽东，却是未曾有过的。我选择了这样的角度来写毛泽东，一方面希望写出新意，另一方面也是希望跟《红色的起点》衔接——因为在中国共产党建立之后，便面临着选择正确而成熟的领袖的问题。领袖是党的旗帜、革命的舵手。列宁曾说：​“历史上，任何一个阶级，如果不推举自己善于组织运动和领导运动的政治领
袖和先进代表，就不可能取得统治地位。​”[插图]他又说：​“政党通常是由最有威信、最有影响、最有经验、被选出担任最重要职务而称为领袖的人们所组成的比较稳定的集团来主持。​”[插图]领袖的选择，对诞生不久、尚处于幼年时期的中国共产党尤为重要。在一定的条件
下，领袖决定一切。在毛泽东之前，一右三“左”​，即陈独秀的右倾机会主义、瞿秋白的“左”倾盲动主义、李立三的“左”倾冒险主义和王明、博古的“左”倾教条主义、宗派主义，正是领袖的错误，导致党走上错误路线。正因为这样，我认为值得从领袖史的角度，去写毛泽东。《红色的起点》采用“T”形结构：既着重写1921年前后中国共产党诞生的历史横断面，也写及中共一大代表们的后来。《历史选择了毛泽
东（为什么是他？他有什么人格魅力？他是怎么做到的？​）​》则采用椭圆形结构，即两头小、中间大。两头，分别是第一章和第八章。第一章《毛泽东之前》​，以粗线条描述在毛泽东以前的中共领袖史，描述了历史对他们的走马灯般的淘汰。如列宁所说：​“他们当领袖是不
合格的，看来他们在革命期间将不得不由领袖变为下属，否则就会被抛弃。​”[插图]第八章《党的领袖》则同样以粗线条描述从遵义会议
确立毛泽东的领袖地位之后，面临张国焘和王明两次严重的挑战，直至中共七大把毛泽东思想作为指导方针写入中共党章。中间的六章，即第二章至第七章，是本书的核心——历史如何选择了毛泽东。从八七会议写起，写井冈山的斗争，写红都瑞金的艰难岁月，写长征中血的教训，写遵义城里那场举世闻名的会议。在这些日子里，毛泽东曾经几度被撤职，几度遭批判，一次被捕，几番病重，真可谓：​“天将降
大任于斯人也，必先苦其心志，劳其筋骨，饿其体肤，空乏其身，行拂乱其所为。​”​（​《孟子·告子下》​）正是在这历史的角逐之中，毛泽东以其正确的思想、策略和路线，脱颖而出，一跃而为中共领袖，从此领导中共达41年之久。我曾说，我的作品是“跑”出来的。在看了大量的历史文献、档案之后，有了总体构思，我便开始“跑”——行程万里，到实地去采访，以尽量掌握丰富的"; // Replace with your novel loading logic
        // Initialize the timer but don't start it yet
        _autoScrollTimer = new Timer.Timer();
    }

    // Process text into lines based on screen width
    private function _processTextIntoLines(dc as Dc) as Void {
        _allLines = [] as Array<String>;
        var screenWidth = dc.getWidth() - 10; // Subtract L/R margin (5+5)
        // Available height for text: total height - top margin (5px) - bottom margin (30px for page num)
        var availableHeight = dc.getHeight() - 35;
        var fontHeight = dc.getFontHeight(_font);
        _linesPerPage = availableHeight / fontHeight;
        if (_linesPerPage <= 0) {
            _linesPerPage = 1; // Ensure at least one line per page
        }

        // Add padding to avoid text touching edges
        _novelText = "\n" + _novelText + "\n";
        var words = _novelText.toCharArray(); // Treat each char as word for simplicity in CJK
        var currentLine = "";
        var textLength = words.size();

        for (var i = 0; i < textLength; i++) {
            var word = words[i].toString();
            var testLine = currentLine.equals("") ? word : currentLine + word;
            var lineWidth = dc.getTextWidthInPixels(testLine, _font);

            if (lineWidth <= screenWidth) {
                currentLine = testLine;
            } else {
                // Add the completed line
                _allLines.add(currentLine);
                // Start a new line with the current word
                currentLine = word;
                // Handle case where a single word is too long
                if (dc.getTextWidthInPixels(currentLine, _font) > screenWidth) {
                    // Simple truncation for now, better handling might be needed
                    // Or find a split point within the word if possible
                    _allLines.add(currentLine.substring(0, 1)); // Add first char
                    currentLine = ""; // Reset line
                }
            }
        }
        // Add the last line if it's not empty
        if (!currentLine.equals("")) {
            _allLines.add(currentLine);
        }

        if (_allLines.size() == 0) {
            _allLines.add("No text"); // Handle empty text case
        }
    }

    // Load your resources here
    function onLayout(dc as Dc) as Void {
        setLayout(Rez.Layouts.MainLayout(dc));
        // Process text initially
        _processTextIntoLines(dc);
    }

    // Called when this View is brought to the foreground. Restore
    // the state of this View and prepare it to be shown. This includes
    // loading resources into memory.
    function onShow() as Void {
    }

    // Update the view
    function scrollDown() as Void {
        var maxStartLine = _allLines.size() - _linesPerPage;
        if (maxStartLine < 0) {
            maxStartLine = 0; // Handle case where text is shorter than one page
        }
        var potentialStartLine = _startLine + 3;
        if (potentialStartLine > maxStartLine) {
            _startLine = maxStartLine;
        } else {
            _startLine = potentialStartLine;
        }
        WatchUi.requestUpdate(); // Request update after changing scroll position
    }

    function scrollUp() as Void {
        var potentialStartLine = _startLine - 3;
        if (potentialStartLine < 0) {
            _startLine = 0;
        } else {
            _startLine = potentialStartLine;
        }
        WatchUi.requestUpdate(); // Request update after changing scroll position
    }

    function onUpdate(dc as Dc) as Void {
        // Call the parent onUpdate function to redraw the layout
        View.onUpdate(dc);

        // Clear the screen
        dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK);
        dc.clear();

        // Ensure startLine is valid
        if (_startLine >= _allLines.size() && _allLines.size() > 0) {
             _startLine = _allLines.size() - 1;
        }
        if (_startLine < 0) {
            _startLine = 0;
        }

        // Draw visible lines
        if (_allLines.size() > 0) {
            dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT);
            var textToDraw = "";
            var endLine = _startLine + _linesPerPage;
            if (endLine > _allLines.size()) {
                endLine = _allLines.size();
            }

            for (var i = _startLine; i < endLine; i++) {
                textToDraw += _allLines[i];
                if (i < endLine - 1) {
                    textToDraw += "\n"; // Add newline between lines
                }
            }

            dc.drawText(
                5, // Left margin
                5, // Top margin
                _font,
                textToDraw,
                Graphics.TEXT_JUSTIFY_LEFT
            );

            // Draw scroll position indicator (optional, e.g., line number or percentage)
            var progressText = Lang.format("$1$/$2$", [_startLine + 1, _allLines.size()]);
            dc.drawText(
                dc.getWidth() / 2,
                dc.getHeight() - 30, // Position at the bottom
                Graphics.FONT_XTINY,
                progressText,
                Graphics.TEXT_JUSTIFY_CENTER
            );
        } else {
             dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT);
             dc.drawText(
                dc.getWidth() / 2,
                dc.getHeight() / 2,
                _font,
                "Loading...",
                Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER
            );
        }
    }

    // Called when this View is removed from the screen. Save the
    // state of this View here. This includes freeing resources from
    // memory.
    function onHide() as Void {
        // Stop the timer if it's running when the view is hidden
        stopAutoScrollTimer();
    }

    // Method to toggle auto-scrolling
    function toggleAutoScroll() as Void {
        _isAutoScrolling = !_isAutoScrolling;
        if (_isAutoScrolling) {
            startAutoScrollTimer();
        } else {
            stopAutoScrollTimer();
        }
        WatchUi.requestUpdate(); // Update UI to potentially show scroll status
    }

    // Start the auto-scroll timer
    hidden function startAutoScrollTimer() as Void {
        if (_autoScrollTimer != null) {
            // Scroll down every 2 seconds (adjust timing as needed)
            _autoScrollTimer.start(method(:autoScrollCallback), 500, true);
        }
    }

    // Stop the auto-scroll timer
    hidden function stopAutoScrollTimer() as Void {
        if (_autoScrollTimer != null) {
            _autoScrollTimer.stop();
        }
        _isAutoScrolling = false; // Ensure state is consistent
    }

    // Callback function for the auto-scroll timer
    function autoScrollCallback() as Void {
        autoScrollDown();
        // No need to call WatchUi.requestUpdate() here, scrollDown does it.
        // If scrollDown reaches the end, it might be desirable to stop the timer.
        // Check if we are at the last page after scrolling.
        if (_startLine >= _allLines.size() - _linesPerPage) {
             stopAutoScrollTimer();
        }
    }

    // Scroll down by one page
    function autoScrollDown() as Void {
        var _linesPerPage = 1;
        if (_startLine < _allLines.size() - _linesPerPage) {
            _startLine += _linesPerPage;
            // Ensure _startLine doesn't exceed the maximum possible start index
            if (_startLine > _allLines.size() - _linesPerPage) {
                _startLine = _allLines.size() - _linesPerPage;
            }
        } else {
            // Optionally stop auto-scroll when reaching the end
            if (_isAutoScrolling) {
                stopAutoScrollTimer();
            }
        }
         if (_startLine < 0) { _startLine = 0; } // Ensure startLine is not negative
        WatchUi.requestUpdate();
    }

    // Scroll up by one page
    function autoScrollUp() as Void {
        var _linesPerPage = 1;
        // Stop auto-scrolling if user manually scrolls up
        if (_isAutoScrolling) {
            stopAutoScrollTimer();
        }
        _startLine -= _linesPerPage;
        if (_startLine < 0) {
            _startLine = 0;
        }
        WatchUi.requestUpdate();
    }

}
